﻿using System;
using System.Web.Mvc;
using ActivateYourGlutes.Services;
using Microsoft.Practices.ServiceLocation;
using Body=ActivateYourGlutes.Services.Model.Body;
using Measurement=ActivateYourGlutes.Services.Model.Measurement;
using MeasurementType=ActivateYourGlutes.Services.Model.MeasurementType;

namespace ActivateYourGlutes.Helpers
{
    public class BodyBinder : IModelBinder
    {
        #region Implementation of IModelBinder

        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.Model != null)
                throw new InvalidOperationException("Unable to update the model");
            var measurementTypeProvider = ServiceLocator.Current.GetInstance<IMeasurementTypeProvider>();
            var accountProvider = ServiceLocator.Current.GetInstance<IAccountProvider>();
            var account = accountProvider.CurrentAccount(controllerContext.HttpContext.User);
            var datetimeBinder = new LocalisedDateTimeBinder();
            var measurementTypes = measurementTypeProvider.MeasurementTypes(account);

            var body = new Body();

            var entryDateValue = bindingContext.ValueProvider.GetValue("EntryDate").AttemptedValue;
            if (!String.IsNullOrEmpty(entryDateValue))
            {
                var boundDateTime = datetimeBinder.BindDate(entryDateValue, controllerContext, bindingContext);
                if (boundDateTime != null)
                    body.EntryDate = boundDateTime.Value;
            }

            var idValue = bindingContext.ValueProvider.GetValue("id").AttemptedValue;
            int id = 0;
            if (!String.IsNullOrEmpty(idValue))
            {
                id = int.Parse(idValue);
            }
            body.BodyId = id;

            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, bindingContext.ValueProvider.GetValue(bindingContext.ModelName));
            foreach(var type in measurementTypes)
            {
                var name = type.ToFormName();
                var value = bindingContext.ValueProvider.GetValue(name).AttemptedValue;
                if (!String.IsNullOrEmpty(value))
                {
                    double parsedValue;
                    if (double.TryParse(value, out parsedValue))
                    {                        
                        var measurement = new Measurement
                                              {
                                                  MeasurementType = new MeasurementType
                                                                        {
                                                                            MeasurementTypeId = type.MeasurementTypeId,
                                                                            Description = type.Description,
                                                                            Type = type.Type
                                                                        },
                                                  LocalisedValue = parsedValue
                                              };
                        body.Measurements.Add(measurement);
                    }
                    else
                    {
                        bindingContext.ModelState.AddModelError(bindingContext.ModelName, String.Format("\"{0}\" is invalid.", type.Description));
                    }
                }
            }
            return body;
        }

        #endregion
    }
}
